/*
 * Copyright (C) 2008, 3apple team, All Rights Reserved
 * Author: James Cook <C.James.CJ@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include "dict_priv.h"

#include <gtk_api.h>

list_head(apple_dicts);

#define for_each_apple_dicts(d)	\
	list_for_each_entry(apple_dict_t, d, &apple_dicts, link)

static int apple_do_dict_init(apple_dict_t *dict);
static void apple_do_dict_exit(apple_dict_t *dict);
static int register_apple_dict(apple_dict_t *dict);
static void unregister_apple_dict(apple_dict_t *dict);

int get_all_words_in_dict(void *up_data, char *output_buf)
{
	apple_dict_t *d;
	uint32_t idx, count;
	char *p, buf[1024];
	int len;
	/* FIXME: rubbish code style. */
	GtkTreeView *view = (GtkTreeView *)up_data;
	p = output_buf;
	for_each_apple_dicts(d) {
		count = d->words_count;
		/* Test only list 10 words in one dictionary. */
		for (idx = 0; idx < 10; idx++) {
			len = get_word_by_idx(d, idx, buf);
			if (len <= 0)
				return 0;
			add_to_list(view, buf);
		}
	}
	return 0;
}

int add_dict_name_banner(char *out, const char *word, const char *name)
{
	int len;
	char buf[1024];

	memset(buf, 0 ,1024);
	sprintf(buf, "<----%s---->\n%s", name, word);
	len = strlen(buf) + 1;
	strcpy(out, buf);
	return len;
}

int get_word_explain(const char *word, char *output_buf)
{
	apple_dict_t *d;
	uint32_t idx;
	char *p, buf[1024];
	int res, total_len = 0, len = 0;

	p = output_buf;
	for_each_apple_dicts(d) {
		idx = find_word_in_idxfile(d, word);
		if (idx != -1) {
			res = add_dict_name_banner(p, word, d->name);

			p[res - 1] = '\n';
			p += res;
			total_len += res;

			memset(buf, 0, 1024);
			len = get_word_meaning_in_dict(d, word, idx, buf);
			assert (len != -1); 
			memcpy(p, buf, len);
			p[len -1] = '\n';
			p += len;
			total_len += len;
		} else {
			printf("\nCannot find word [%s] in [%s].\n", word, d->name);
			strcpy(output_buf, "Cannot find word");
		}
	}
	if (total_len > 0)
		p[total_len - 1] = 0;
	return total_len;
}

int apple_do_dicts_init(apple_dict_t *dict, int n)
{
	int i, res = -1;
	for (i = 0; i < n; ++i) {
		res = apple_do_dict_init(&dict[i]);
		/* Cannot init files, remove it from our list. */
		if (res != 0)
			unregister_apple_dict(&dict[i]);
	}
	return 0;
}

static int apple_do_dict_init(apple_dict_t *dict)
{
	int res;
	
	/* open dictionary files: ifo / idx / dict */
	res = open_dict_files(dict);
	if (res == -1)
		return -1;
	res = parse_ifo_file(dict);
	if (res == -1)
		return -1;

	dict->idxbuff = malloc(sizeof (uint32_t) * dict->words_count);

	if (!dict->idxbuff) {
		printf("Out of mem\n");
		return -1;
	}

	memset(dict->idxbuff, 0, sizeof (uint32_t) * dict->words_count);

	parse_idx_file(dict);
	printf("idx file parse finish.\n word_count: %ld\n idx_size: %ld\n\n\n", 
		dict->words_count, dict->idx_size);

	return 0;
}

static void apple_do_dict_exit(apple_dict_t *dict)
{
	if (dict->fd_ifo > 0) close(dict->fd_ifo);
	if (dict->fd_idx > 0) close(dict->fd_idx);
	if (dict->fd_dict > 0) close(dict->fd_dict);
	if (dict->idxbuff)
		free(dict->idxbuff);
}

void apple_do_dicts_exit(apple_dict_t *dict, int n)
{
	int i;
	for (i = 0; i < n; ++i)
		apple_do_dict_exit(&dict[i]);
}

apple_dict_t *apple_find_dict(const char *name)
{
	list_t *n, *pos;
	apple_dict_t *dict;

	list_iterate_forward(pos, n, &apple_dicts) {
		dict = list_entry(pos, apple_dict_t, link);
		if (strcasecmp(dict->name, name) == 0)
			return dict;
	}
	return NULL;
}

int register_apple_dicts(apple_dict_t *dict, int n)
{
	int i;
	for (i = 0; i < n; ++i)
		register_apple_dict(&dict[i]);
	return 0;
}

static int register_apple_dict(apple_dict_t *dict)
{
	if (dict) {
		if (apple_find_dict(dict->name)) {
			printf("DICT: already registered dict, dict=%s",
				dict->name);
			return 0;
		}
		list_init(&dict->link);
		list_insert_before(&dict->link, &apple_dicts);
	}
	return 0;

}

static void unregister_apple_dict(apple_dict_t *dict)
{
	if (dict) {
		if (apple_find_dict(dict->name))
			list_delete_init(&dict->link);
	}
}
void unregister_apple_dicts(apple_dict_t *dict, int n)
{
	int i;
	for (i = 0; i < n; ++i)
		unregister_apple_dict(&dict[i]);
}

/* init all register dict.
 * FIXME: can walk the dict list.
 */
int apple_dict_init(void)
{
	apple_stardict_dict_init();

	return 0;
}

void apple_dict_exit(void)
{
	apple_stardict_dict_exit();
}
